home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / mono.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  5KB  |  217 lines

  1. /*
  2.  * Author:    Yoichiro Ueno (ueno@cs.titech.ac.jp)
  3.  *
  4.  * Copyright (C) 1991, 1992, Yoichiro Ueno.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and
  7.  * its documentation for any purpose is hereby granted by the Author without
  8.  * fee, provided that the above copyright notice appear in all copies and
  9.  * that both the copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of the Author not be used
  11.  * in advertising or publicity pertaining to distribution of the software
  12.  * without specific, written prior permission.  The Author makes no
  13.  * representations about the suitability of this software for any purpose.
  14.  * It is provided "as is" without express or implied warranty.
  15.  *
  16.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  18.  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  20.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  21.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  22.  * PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  */
  25.  
  26. #include "video.h"
  27. #include "proto.h"
  28. #include "dither.h"
  29.  
  30.  
  31.  
  32. /*
  33.  *--------------------------------------------------------------
  34.  *
  35.  * MonoDitherImage --
  36.  *
  37.  *    Dithers image into monochrome.
  38.  *    Dither algorithm is based on dither.c in xli.1.11.
  39.  *
  40.  * Results:
  41.  *    None.
  42.  *
  43.  * Side effects:
  44.  *    None.
  45.  *
  46.  *--------------------------------------------------------------
  47.  */
  48. #define MaxGrey        65280
  49. #define Threshold    (MaxGrey/2)
  50. #define MinGrey        0
  51.  
  52. #if LITTLE_ENDIAN_ARCHITECTURE
  53. #    define SEED_BIT 0x01
  54. #    define OPP_SEED_BIT 0x80
  55. #    define SHIFT_SEED_BIT(b) (b <<= 1)
  56. #    define OPP_SHIFT_SEED_BIT(b) (b >>= 1)
  57. #else
  58. #    define SEED_BIT 0x80
  59. #    define OPP_SEED_BIT 0x01
  60. #    define SHIFT_SEED_BIT(b) (b >>= 1)
  61. #    define OPP_SHIFT_SEED_BIT(b) (b <<= 1)
  62. #endif
  63.  
  64. static int    *curr = NULL;
  65. static int    *next = NULL;
  66.  
  67. void
  68. MonoDitherImage(lum, cr, cb, out, h, w)
  69.     register unsigned char *lum;
  70.     unsigned char *cr;
  71.     unsigned char *cb;
  72.     register unsigned char *out;
  73.     int w, h;
  74. {
  75.   int bit_r2l;
  76.   register unsigned int bit;
  77.   register unsigned int data;
  78.   int i;
  79.   register int j;
  80.   int *swap;
  81.   register int out_err;
  82.   register int next1;
  83.   register int next2;
  84.  
  85.   if (curr == NULL) {
  86.     curr = (int *)malloc((unsigned int) sizeof(int) * (w + 2));
  87.     curr += 1;
  88.   }
  89.   if (next == NULL) {
  90.     next = (int *)malloc((unsigned int) sizeof(int) * (w + 2));
  91.     next += 1;
  92.   }
  93.  
  94.   memset ((char *)curr, 0, (size_t)w * sizeof(*curr));
  95.  
  96.   bit_r2l = SEED_BIT << (w - 1 & 7);
  97.   for (i = 0; i < h; i ++) {
  98.     if (i & 0x01) {                /* Right to Left */
  99.       bit = bit_r2l;
  100.       data = 0;
  101.       out_err = curr[w-1];
  102.       next1 = 0;
  103.       next2 = 0;
  104.       for (j=(w-1); j>=0; j--)
  105.       {
  106.         out_err = (out_err >> 4) + (lum[j] << 8);
  107.         if (out_err > Threshold) {
  108.           data |= bit;
  109.           out_err -= MaxGrey;
  110.         }
  111.         else
  112.           out_err -= MinGrey;
  113.  
  114.         next[j+1] = next1 +     (out_err * 3);
  115.         next1     = next2 +     (out_err * 5);
  116.         next2     =             (out_err * 1);
  117.         out_err   = curr[j-1] + (out_err * 7);
  118.  
  119.         OPP_SHIFT_SEED_BIT(bit);
  120. #if LITTLE_ENDIAN_ARCHITECTURE
  121.         if (bit == 0) {
  122. #else
  123.         if (bit > 0x80) {
  124. #endif
  125.           out[j >> 3] = data;
  126.           bit = OPP_SEED_BIT;
  127.           data = 0;
  128.         }
  129.       }
  130.       next[0] = next1;
  131.     }
  132.     else {                    /* Left to Right */
  133.       bit = SEED_BIT;
  134.       data = 0;
  135.       out_err = curr[0];
  136.       next1 = 0;
  137.       next2 = 0;
  138.       for (j=0; j<w; j++)
  139.       {
  140.         out_err = (out_err >> 4) + (lum[j] << 8);
  141.         if (out_err > Threshold) {
  142.           data |= bit;
  143.           out_err = out_err - MaxGrey;
  144.         }
  145.         else
  146.           out_err = out_err - MinGrey;
  147.  
  148.         next[j-1] = next1 +     (out_err * 3);
  149.         next1     = next2 +     (out_err * 5);
  150.         next2     =             (out_err * 1);
  151.         out_err   = curr[j+1] + (out_err * 7);
  152.  
  153.         SHIFT_SEED_BIT(bit);
  154. #if LITTLE_ENDIAN_ARCHITECTURE
  155.         if (bit > 0x80) {
  156. #else
  157.         if (bit == 0) {
  158. #endif
  159.           out[j >> 3] = data;
  160.           bit = SEED_BIT;
  161.           data = 0;
  162.         }
  163.       }
  164.       next[w-1] = next1;
  165.     }
  166.     
  167.     lum += w;
  168.     out += w >> 3;
  169.     swap = curr;
  170.     curr = next;
  171.     next = swap;
  172.   }
  173. }
  174.  
  175.  
  176.  
  177. /*
  178.  *--------------------------------------------------------------
  179.  *
  180.  * MonoThresholdImage --
  181.  *
  182.  *    convert image into monochrome with threshold.
  183.  *
  184.  * Results:
  185.  *    None.
  186.  *
  187.  * Side effects:
  188.  *    None.
  189.  *
  190.  *--------------------------------------------------------------
  191.  */
  192. void
  193. MonoThresholdImage(lum, cr, cb, out, h, w)
  194.     unsigned char *lum;
  195.     unsigned char *cr;
  196.     unsigned char *cb;
  197.     unsigned char *out;
  198.     int w, h;
  199. {
  200.   unsigned char bit;
  201.   unsigned char data;
  202.  
  203.   bit = SEED_BIT;
  204.   data = 0;
  205.   for (w*=h; w>0; w--) {
  206.     if(*lum++>128)
  207.       data |= bit;
  208.  
  209.     SHIFT_SEED_BIT(bit);
  210.     if(bit == 0) {
  211.       *out ++ = data;
  212.       bit = SEED_BIT;
  213.       data = 0;
  214.     }
  215.   }
  216. }
  217.